﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.Windows.Controls.Primitives;

using Microsoft.Xna.Framework.Input.Touch;

using BlobTowerDefense.Game_Entities;
using BlobTowerDefense.Managers;
using BlobTowerDefense.Tools;

using Matrix = Microsoft.Xna.Framework.Matrix;
using BlobTowerDefense.Custom_Controls;
using System.Windows.Media.Imaging;
using ShakeGestures;
using BlobTowerDefense.Resources;

namespace BlobTowerDefense
{
    public enum DIFFICULTY { Easy, Medium, Hard };

    public partial class GamePage : PhoneApplicationPage
    {
        public static ContentManager content;
        GameTimer timer;
        SpriteBatch spriteBatch;
        UIElementRenderer elementRenderer;
        public static GraphicsDevice Device;
        public static DIFFICULTY Difficulty;

        private Camera camera;
        private RenderTarget2D renderTarget;
        
        // managers
        WorldManager worldManager;

        // Matrices for 3D
        Matrix projection;
        Matrix view;
        Matrix world;

        private bool? isSpecialAttackActive;

        BitmapImage bitmap_SpecialAttack_on;
        BitmapImage bitmap_SpecialAttack_off;

        int time;
        int timeSpecialAttackPeriod = 100;

        bool tapOnControl;

        public static int PlayerMoney = 1000;
        public static int PlayerHP = 25;
        private static int AddedMoneyAfterWave = 200;
        private static int AddedMoneyAfterLevel = 1000;

        private const int PlayerHP_Easy = 30;
        private const int PlayerHP_Medium = 20;
        private const int PlayerHP_Hard = 10;

        private const int PlayerMoney_Easy = 1000;
        private const int PlayerMoney_Medium = 750;
        private const int PlayerMoney_Hard = 500;

        private const int AddeMoneyAfterWave_Easy = 200;
        private const int AddeMoneyAfterWave_Medium = 100;
        private const int AddeMoneyAfterWave_Hard = 0;

        private const int AddedMoneyAfterLevel_Easy = 1000;
        private const int AddedMoneyAfterLevel_Medium = 750;
        private const int AddedMoneyAfterLevel_Hard = 500;

        public static int WorldIndex;

        private bool isGameOver = false;

        Texture2D backgroundTexture;

        public GamePage()
        {
        }

        private void initGamePage()
        {
            InitializeComponent();

            // Get the content manager from the application
            content = (Application.Current as App).Content;
            try
            {
                content.RootDirectory = "content";
            }
            catch (InvalidOperationException)
            {
            }

            // Create a timer for this page
            timer = new GameTimer();
            timer.UpdateInterval = TimeSpan.FromTicks(333333);
            timer.Update += OnUpdate;
            timer.Draw += OnDraw;

            LayoutUpdated += new EventHandler(GamePage_LayoutUpdated);

            //SharedGraphicsDeviceManager.Current.PreferredBackBufferWidth = 800;
            //SharedGraphicsDeviceManager.Current.ApplyChanges();

            Device = SharedGraphicsDeviceManager.Current.GraphicsDevice;

            // Set Touchscreen gestures
            TouchPanel.EnabledGestures = GestureType.FreeDrag | GestureType.Pinch | GestureType.Tap;

            // Managers definitions
            worldManager = new WorldManager(content);

            // 3D Matrix
            float aspectRation = (float)Device.Viewport.Width / (float)Device.Viewport.Height;
            float fov = MathHelper.PiOver4 * aspectRation * 3 / 4;
            projection = Matrix.CreatePerspectiveFieldOfView(fov, aspectRation, 1, 1000);
            view = Matrix.CreateLookAt(new Vector3(0.0f, 5.0f, 10.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
            world = Matrix.Identity;

            //Camera class
            camera = new Camera();


            // Load all data for loading worlds
            //Loader loader = new Loader(worldManager, enemyManager, Device);
            Loader loader = new Loader(worldManager);
            loader.FillAllData();

            //start timer for level
            //enemyManager.StartTimer();

            initToggleButtons_Custom();

            translate_TowerStats.Y = -200;

            isSpecialAttackActive = false;
            ShakeGesturesHelper.Instance.ShakeGesture += new EventHandler<ShakeGestureEventArgs>(Instance_ShakeGesture);
            ShakeGesturesHelper.Instance.MinimumRequiredMovesForShake = 5;

            bitmap_SpecialAttack_on = new BitmapImage(new Uri("../Images/OtherIcons/special_attack_on.png", UriKind.Relative));
            bitmap_SpecialAttack_off = new BitmapImage(new Uri("../Images/OtherIcons/special_attack_off.png", UriKind.Relative));

            time = 0;

            animation_NextWave_Hide_BuildingMode.Completed += new EventHandler(animation_NextWave_Hide_BuildingMode_Completed);
            animation_NextWave_Hide_LaunchWave.Completed += new EventHandler(animation_NextWave_Hide_LaunchWave_Completed);
            animation_NextWave_Show.Completed += new EventHandler(animation_NextWave_Show_Completed);            
        }

        private void initToggleButtons_Custom()
        {
            ToggleButton_Tower01.TowerStats = TowerManager.DefaultTowerStats[TOWERTYPE.tower1];
            ToggleButton_Tower02.TowerStats = TowerManager.DefaultTowerStats[TOWERTYPE.tower2];
            ToggleButton_Tower03.TowerStats = TowerManager.DefaultTowerStats[TOWERTYPE.tower3];
            ToggleButton_Tower04.TowerStats = TowerManager.DefaultTowerStats[TOWERTYPE.tower4];
            ToggleButton_Tower05.TowerStats = TowerManager.DefaultTowerStats[TOWERTYPE.tower5];
            ToggleButton_Tower06.TowerStats = TowerManager.DefaultTowerStats[TOWERTYPE.tower6];
        }

        void GamePage_LayoutUpdated(object sender, EventArgs e)
        {
            // Create the UIElementRenderer to draw the XAML page to a texture.

            // Check for 0 because when we navigate away the LayoutUpdate event
            // is raised but ActualWidth and ActualHeight will be 0 in that case.
            if ((ActualWidth > 0) && (ActualHeight > 0))
            {
                SharedGraphicsDeviceManager.Current.PreferredBackBufferWidth = (int)ActualWidth;
                SharedGraphicsDeviceManager.Current.PreferredBackBufferHeight = (int)ActualHeight;

                if (null == elementRenderer)
                {
                    elementRenderer = new UIElementRenderer(this, (int)ActualWidth, (int)ActualHeight);
                }
            }
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            initGamePage();
            // Set the sharing mode of the graphics device to turn on XNA rendering
            SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(true);

            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager.Current.GraphicsDevice);

            renderTarget = new RenderTarget2D(SharedGraphicsDeviceManager.Current.GraphicsDevice,
                                              SharedGraphicsDeviceManager.Current.PreferredBackBufferWidth,
                                              SharedGraphicsDeviceManager.Current.PreferredBackBufferHeight,
                                              false,
                                              SurfaceFormat.Color,
                                              DepthFormat.Depth16);

            string Difficulty_string;

            if (NavigationContext.QueryString.TryGetValue("Difficulty", out Difficulty_string))
            {
                switch (Difficulty_string)
                {
                    case "Easy":
                        Difficulty = DIFFICULTY.Easy;
                        break;
                    case "Medium":
                        Difficulty = DIFFICULTY.Medium;
                        break;
                    case "Hard":
                        Difficulty = DIFFICULTY.Hard;
                        break;
                    default:
                        Difficulty = DIFFICULTY.Easy;
                        break;
                }

                SetDifficultySettings(Difficulty);
            }
            else
            {
                Difficulty = DIFFICULTY.Easy;
                SetDifficultySettings(Difficulty);
            }

            string Continue_string;

            if (NavigationContext.QueryString.TryGetValue("Continue", out Continue_string))
            {
                if (Continue_string == "1")
                {
                    WAVETYPE? currentWaveType = Loader.Load_SavedWaveType();
                    if (currentWaveType != null)
                    {
                        if (currentWaveType <= WAVETYPE.WAVE5)
                        {
                            // Load models to game
                            worldManager.LoadWorld(0);
                            WorldIndex = 0;

                            List<Tower> savedTowers = Loader.Load_SavedTowers();
                            if (savedTowers != null)
                            {
                                TowerManager.Towers = savedTowers;
                            }
                        }
                        else
                        {
                            // Load models to game
                            worldManager.LoadWorld(1);
                            WorldIndex = 1;

                            List<Tower> savedTowers = Loader.Load_SavedTowers();
                            if (savedTowers != null)
                            {
                                TowerManager.Towers = savedTowers;
                            }
                        }

                        if (currentWaveType != WAVETYPE.WAVE1)
                        {
                            currentWaveType--;
                            WaveManager.CurrentWaveType = (WAVETYPE)currentWaveType;
                            WaveManager.CurrentWave = WaveManager.DefaultWaves_Level1[WaveManager.CurrentWaveType];
                        }
                    }

                    DIFFICULTY? savedDifficulty = Loader.Load_SavedDifficulty();
                    if (savedDifficulty == null)
                    {
                        Difficulty = DIFFICULTY.Easy;
                    }
                    else
                    {
                        Difficulty = (DIFFICULTY)savedDifficulty;
                    }

                    PlayerHP = Loader.Load_SavedPlayerHP();
                    PlayerMoney = Loader.Load_SavedPlayerMoney();
                }
                else
                {
                    worldManager.LoadWorld(0);
                    WorldIndex = 0;
                }
            }
            else
            {
                worldManager.LoadWorld(0);
                WorldIndex = 0;
            }

            backgroundTexture = GamePage.content.Load<Texture2D>("Images/Backgrounds/clouds_background");
            

            showNextWave();

            // Load enemies in the world
            //enemyManager.LoadWorld();

            // Start the timer
            timer.Start();

            base.OnNavigatedTo(e);
        }

        private void SetDifficultySettings(DIFFICULTY difficulty)
        {
            switch (difficulty)
            {
                case DIFFICULTY.Easy:
                    PlayerHP = PlayerHP_Easy;
                    PlayerMoney = PlayerMoney_Easy;
                    AddedMoneyAfterWave = AddeMoneyAfterWave_Easy;
                    AddedMoneyAfterLevel = AddedMoneyAfterLevel_Easy;
                    break;
                case DIFFICULTY.Medium:
                    PlayerHP = PlayerHP_Medium;
                    PlayerMoney = PlayerMoney_Medium;
                    AddedMoneyAfterWave = AddeMoneyAfterWave_Medium;
                    AddedMoneyAfterLevel = AddedMoneyAfterLevel_Medium;
                    break;
                case DIFFICULTY.Hard:
                    PlayerHP = PlayerHP_Hard;
                    PlayerMoney = PlayerMoney_Hard;
                    AddedMoneyAfterWave = AddeMoneyAfterWave_Hard;
                    AddedMoneyAfterLevel = AddedMoneyAfterLevel_Hard;
                    break;
            }
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            // Stop the timer
            timer.Stop();

            // Set the sharing mode of the graphics device to turn off XNA rendering
            SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(false);

            base.OnNavigatedFrom(e);
        }

        /// <summary>
        /// Allows the page to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        private void OnUpdate(object sender, GameTimerEventArgs e)
        {
            if (!isGameOver && (PlayerHP <= 0))
            {
                isGameOver = true;
                TextBox_Nickname.Text = Loader.Load_NickName();
                TextBlock_HighScore.Text = countHighScore().ToString();
                if (CursorState.IsTowerSelected)
                {
                    animation_TowerStats_Hide.Begin();
                    ToggleButton_Tower01.IsEnabled = false;
                    ToggleButton_Tower02.IsEnabled = false;
                    ToggleButton_Tower03.IsEnabled = false;
                    ToggleButton_Tower04.IsEnabled = false;
                    ToggleButton_Tower05.IsEnabled = false;
                    ToggleButton_Tower06.IsEnabled = false;
                }

                animation_GameOver_Show.Begin();
            }
            
            if(!isGameOver)
            {
                time++;

                if (time > timeSpecialAttackPeriod)
                {
                    if ((isSpecialAttackActive != null) && ((bool)isSpecialAttackActive == false))
                    {
                        Image_SpecialAttack.Source = new BitmapImage(new Uri("../Images/OtherIcons/special_attack_on.png", UriKind.Relative));
                        isSpecialAttackActive = true;
                    }

                    time = 0;
                }

                if (this.worldManager.WaveRunning())
                {
                    if (this.worldManager.WaveEnded())
                    {
                        PlayerMoney += AddedMoneyAfterWave;
                        if (worldManager.GetCurrentWaveType() == WAVETYPE.WAVE15)
                        {
                            isGameOver = true;
                            TextBox_Nickname.Text = Loader.Load_NickName();
                            TextBlock_HighScore.Text = countHighScore().ToString();
                            if (CursorState.IsTowerSelected)
                            {
                                animation_TowerStats_Hide.Begin();
                                ToggleButton_Tower01.IsEnabled = false;
                                ToggleButton_Tower02.IsEnabled = false;
                                ToggleButton_Tower03.IsEnabled = false;
                                ToggleButton_Tower04.IsEnabled = false;
                                ToggleButton_Tower05.IsEnabled = false;
                                ToggleButton_Tower06.IsEnabled = false;
                            }

                            animation_GameOver_Show.Begin();
                        }
                        showNextWave();
                    }
                }

                if (isSpecialAttackActive == null)
                {
                    Image_SpecialAttack.Source = new BitmapImage(new Uri("../Images/OtherIcons/special_attack_off.png", UriKind.Relative));
                    isSpecialAttackActive = false;
                    ShakeGesturesHelper.Instance.Active = false;
                }
                else if ((bool)isSpecialAttackActive)
                {
                    ShakeGesturesHelper.Instance.Active = true;
                }

                if ((!CursorState.IsTowerSelected) && (translate_TowerStats.Y == 0))
                {
                    animation_TowerStats_Hide.Begin();
                }

                if (TouchPanel.IsGestureAvailable)
                {
                    if (!tapOnControl)
                    {
                        GestureSample gesture = TouchPanel.ReadGesture();
                        CursorState.Position = gesture.Position;
                        CursorState.Gesture = gesture;
                    }
                    else
                    {
                        tapOnControl = false;
                    }
                }

                if (CursorState.IsTowerSelected)
                {
                    updateTextStats(CursorState.TowerSelectedStats);
                    if (TowerManager.DefaultTowerStats[CursorState.TowerSelectedStats.TowerType].IsUpgraded)
                    {
                        Button_TowerUpgrade.IsEnabled = false;
                    }
                    else
                    {
                        Button_TowerUpgrade.IsEnabled = true;
                    }
                }
                else
                {
                    toggleButtons_Reset();
                }
            }

            camera.Update();
            worldManager.getWorld().Update();

            TextBlock_HP.Text = GamePage.PlayerHP.ToString();
            TextBlock_Coins.Text = GamePage.PlayerMoney.ToString();
        }

        private void updateTextStats(TowerStats towerStats)
        {
            if (TowerManager.DefaultTowerStats[CursorState.TowerSelectedStats.TowerType].IsUpgraded)
            {
                TextBlock_Cost.Text = StringFormatting.FormatTowerStatus(TextBlock_Cost.Text, towerStats.Cost);
                TextBlock_Damage.Text = StringFormatting.FormatTowerStatus(TextBlock_Damage.Text, towerStats.UpgradedDamage, towerStats.UpgradedDamage);
                TextBlock_Range.Text = StringFormatting.FormatTowerStatus(TextBlock_Range.Text, towerStats.UpgradedRange, towerStats.UpgradedRange);
                TextBlock_Special.Text = StringFormatting.FormatTowerStatus(TextBlock_Special.Text, ApplicationResources.Get(String.Format("Special_{0}", towerStats.Special)));
                TextBlock_Speed.Text = StringFormatting.FormatTowerStatus(TextBlock_Speed.Text, towerStats.UpgradedSpeed, towerStats.Speed);
                TextBlock_UpgradeCost.Text = StringFormatting.FormatTowerStatus(TextBlock_UpgradeCost.Text, towerStats.UpgradeCost);                
            }
            else
            {
                TextBlock_Cost.Text = StringFormatting.FormatTowerStatus(TextBlock_Cost.Text, towerStats.Cost);
                TextBlock_Damage.Text = StringFormatting.FormatTowerStatus(TextBlock_Damage.Text, towerStats.Damage, towerStats.UpgradedDamage);
                TextBlock_Range.Text = StringFormatting.FormatTowerStatus(TextBlock_Range.Text, towerStats.Range, towerStats.UpgradedRange);
                TextBlock_Special.Text = StringFormatting.FormatTowerStatus(TextBlock_Special.Text, ApplicationResources.Get(String.Format("Special_{0}", towerStats.Special)));
                TextBlock_Speed.Text = StringFormatting.FormatTowerStatus(TextBlock_Speed.Text, towerStats.Speed, towerStats.Speed);
                TextBlock_UpgradeCost.Text = StringFormatting.FormatTowerStatus(TextBlock_UpgradeCost.Text, towerStats.UpgradeCost);
            }            
        }


        /// <summary>
        /// Allows the page to draw itself.
        /// </summary>
        private void OnDraw(object sender, GameTimerEventArgs e)
        {
            GamePage.Device.SetRenderTarget(renderTarget);
            elementRenderer.Render();

            GamePage.Device.SetRenderTarget(null);            

            spriteBatch.Begin();

            DrawBackground();

            spriteBatch.End();

            //GamePage.Device.Clear(ClearOptions.DepthBuffer | ClearOptions.Target, Microsoft.Xna.Framework.Color.Black, 1, 0);

            //Enable depth buffer
            Device.DepthStencilState = DepthStencilState.Default;

            //Device.DepthStencilState = DepthStencilState.Default;

            // XNA drawing
            //World world = worldManager.getWorld();
            //if (world != null)
            //    world.Draw();
            worldManager.DrawActiveWorld();
            //enemyManager.DrawAll();


            // Silverlight drawing
            spriteBatch.Begin();            

            spriteBatch.Draw(elementRenderer.Texture, Vector2.Zero, Microsoft.Xna.Framework.Color.White);

            spriteBatch.End();
        }

        private void DrawBackground()
        {
            int screenWidth = GamePage.Device.PresentationParameters.BackBufferWidth;
            int screenHeight = GamePage.Device.PresentationParameters.BackBufferHeight;

            Microsoft.Xna.Framework.Rectangle screenRectangle = new Microsoft.Xna.Framework.Rectangle(0, 0, screenWidth, screenHeight);
            spriteBatch.Draw(backgroundTexture, screenRectangle, Microsoft.Xna.Framework.Color.White);
        }

        private void Page_GamePage_OrientationChanged(object sender, OrientationChangedEventArgs e)
        {
            renderTarget = new RenderTarget2D(SharedGraphicsDeviceManager.Current.GraphicsDevice,
                                              SharedGraphicsDeviceManager.Current.PreferredBackBufferWidth,
                                              SharedGraphicsDeviceManager.Current.PreferredBackBufferHeight,
                                              false,
                                              SurfaceFormat.Color,
                                              DepthFormat.Depth16);

            elementRenderer = new UIElementRenderer(this, (int)ActualWidth, (int)ActualHeight);

            if ((e.Orientation & PageOrientation.Landscape) == (PageOrientation.Landscape))
            {
                if (Loader.Load_LeftHanded())
                {   
                    LayoutRoot.ColumnDefinitions[0].Width = new GridLength(1, GridUnitType.Auto);
                    LayoutRoot.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);

                    Grid.SetRow(StackPanel_Towers, 0);
                    Grid.SetRowSpan(StackPanel_Towers, 4);
                    Grid.SetColumn(StackPanel_Towers, 0);
                    StackPanel_Towers.Orientation = System.Windows.Controls.Orientation.Vertical;

                    Grid.SetColumn(Canvas_TowerStats, 1);
                    Grid.SetColumn(Grid_PlayerStats, 1);
                    Grid_PlayerStats.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
                    Grid.SetColumn(Image_SpecialAttack, 1);
                    Grid.SetColumn(Image_Coins, 1);
                    Grid.SetColumn(Image_HP, 1);
                    Grid.SetColumn(TextBlock_Coins, 0);
                    Grid.SetColumn(TextBlock_HP, 0);
                    TextBlock_Coins.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
                    TextBlock_HP.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;

                    Grid.SetRow(Grid_NextWave, 1);
                    Grid.SetColumn(Grid_NextWave, 2);
                }
                else
                {
                    LayoutRoot.ColumnDefinitions[0].Width = new GridLength(1, GridUnitType.Star);
                    LayoutRoot.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Auto);

                    Grid.SetRow(StackPanel_Towers, 0);
                    Grid.SetRowSpan(StackPanel_Towers, 4);
                    Grid.SetColumn(StackPanel_Towers, 1);
                    StackPanel_Towers.Orientation = System.Windows.Controls.Orientation.Vertical;

                    Grid.SetColumn(Canvas_TowerStats, 0);
                    Grid.SetColumn(Grid_PlayerStats, 0);
                    Grid_PlayerStats.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                    Grid.SetColumn(Image_SpecialAttack, 0);
                    Grid.SetColumn(Image_Coins, 0);
                    Grid.SetColumn(Image_HP, 0);
                    Grid.SetColumn(TextBlock_Coins, 1);
                    Grid.SetColumn(TextBlock_HP, 1);
                    TextBlock_Coins.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                    TextBlock_HP.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;

                    Grid.SetRow(Grid_NextWave, 1);
                    Grid.SetColumn(Grid_NextWave, 0);
                }

                Grid_TowerStats.ColumnDefinitions[0].Width = new GridLength(241);
                Grid_TowerStats.ColumnDefinitions[1].Width = new GridLength(241);
                Grid_TowerStats.ColumnDefinitions[2].Width = new GridLength(241);

                Grid.SetColumn(TextBlock_Damage, 0);
                Grid.SetColumn(TextBlock_Range, 0);
                Grid.SetColumn(TextBlock_Speed, 1);
                Grid.SetColumn(TextBlock_Special, 1);
                Grid.SetColumn(TextBlock_Cost, 2);
                Grid.SetColumn(TextBlock_UpgradeCost, 2);

                Grid.SetRow(TextBlock_Damage, 0);
                Grid.SetRow(TextBlock_Range, 1);
                Grid.SetRow(TextBlock_Speed, 0);
                Grid.SetRow(TextBlock_Special, 1);
                Grid.SetRow(TextBlock_Cost, 0);
                Grid.SetRow(TextBlock_UpgradeCost, 1);

                Grid.SetColumn(Button_TowerUpgrade, 2);
                
                Grid.SetRow(Button_NextWave, 1);
                Grid.SetColumn(Button_NextWave, 1);
                Grid.SetRow(TextBlock_WaveNumber, 1);
                Grid.SetColumn(TextBlock_WaveNumber, 1);
            }
            else
            {
                LayoutRoot.ColumnDefinitions[0].Width = new GridLength(1, GridUnitType.Star);
                LayoutRoot.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Auto);

                Grid.SetRow(StackPanel_Towers, 3);
                Grid.SetRowSpan(StackPanel_Towers, 1);
                Grid.SetColumn(StackPanel_Towers, 0);
                StackPanel_Towers.Orientation = System.Windows.Controls.Orientation.Horizontal;

                Grid.SetColumn(Canvas_TowerStats, 0);
                Grid.SetColumn(Button_TowerUpgrade, 1);               

                Grid_TowerStats.ColumnDefinitions[0].Width = new GridLength(240);
                Grid_TowerStats.ColumnDefinitions[1].Width = new GridLength(240);
                Grid_TowerStats.ColumnDefinitions[2].Width = new GridLength(0);

                Grid.SetColumn(TextBlock_Damage, 0);
                Grid.SetColumn(TextBlock_Range, 0);
                Grid.SetColumn(TextBlock_Speed, 0);
                Grid.SetColumn(TextBlock_Special, 1);
                Grid.SetColumn(TextBlock_Cost, 1);
                Grid.SetColumn(TextBlock_UpgradeCost, 1);

                Grid.SetRow(TextBlock_Damage, 0);
                Grid.SetRow(TextBlock_Range, 1);
                Grid.SetRow(TextBlock_Speed, 2);
                Grid.SetRow(TextBlock_Special, 0);
                Grid.SetRow(TextBlock_Cost, 1);
                Grid.SetRow(TextBlock_UpgradeCost, 2);

                Grid.SetColumn(Grid_PlayerStats, 0);
                Grid_PlayerStats.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                Grid.SetColumn(Image_SpecialAttack, 0);
                Grid.SetColumn(Image_Coins, 0);
                Grid.SetColumn(Image_HP, 0);
                Grid.SetColumn(TextBlock_Coins, 1);
                Grid.SetColumn(TextBlock_HP, 1);
                TextBlock_Coins.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                TextBlock_HP.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;

                Grid.SetRow(Grid_NextWave, 2);
                Grid.SetColumn(Grid_NextWave, 0);

                Grid.SetRow(Button_NextWave, 2);
                Grid.SetColumn(Button_NextWave, 0);
                Grid.SetRow(TextBlock_WaveNumber, 2);
                Grid.SetColumn(TextBlock_WaveNumber, 0);
            }
        }

        private void ToggleButton_Tower_Checked(object sender, RoutedEventArgs e)
        {
            ToggleButton_Custom custom1 = ToggleButton_Tower01;
            ToggleButton_Custom custom2 = ToggleButton_Tower02;
            ToggleButton_Custom custom3 = ToggleButton_Tower03;
            ToggleButton_Custom custom4 = ToggleButton_Tower04;
            ToggleButton_Custom custom5 = ToggleButton_Tower05;
            ToggleButton_Custom custom6 = ToggleButton_Tower06;

            bool isSelected1 = ToggleButton_Tower01.IsSelected;
            bool isSelected2 = ToggleButton_Tower02.IsSelected;
            bool isSelected3 = ToggleButton_Tower03.IsSelected;
            bool isSelected4 = ToggleButton_Tower04.IsSelected;
            bool isSelected5 = ToggleButton_Tower05.IsSelected;
            bool isSelected6 = ToggleButton_Tower06.IsSelected;
            
            if (((ToggleButton_Custom)sender).IsSelected)
            {
                animation_TowerStats_Hide.Begin();
                CursorState.IsTowerSelected = false;

                ((ToggleButton_Custom)sender).IsSelected = false;
                ((ToggleButton_Custom)sender).IsChecked = false;
                ((ToggleButton_Custom)sender).BorderThickness = new Thickness(0);
            }
            else
            {
                animation_TowerStats_Show.Begin();
                CursorState.IsTowerSelected = true;
                CursorState.TowerSelectedStats = ((ToggleButton_Custom)sender).TowerStats;
                CursorState.Position = new Vector2(-1.0f);
                CursorState.Gesture = new GestureSample();

                toggleButtons_Reset();
                ((ToggleButton_Custom)sender).IsSelected = true;
                ((ToggleButton_Custom)sender).IsChecked = false;
                ((ToggleButton_Custom)sender).BorderThickness = new Thickness(5);
            }
        }

        private void toggleButtons_Reset()
        {
            ToggleButton_Tower01.IsSelected = false;
            ToggleButton_Tower02.IsSelected = false;
            ToggleButton_Tower03.IsSelected = false;
            ToggleButton_Tower04.IsSelected = false;
            ToggleButton_Tower05.IsSelected = false;
            ToggleButton_Tower06.IsSelected = false;

            ToggleButton_Tower01.BorderThickness = new Thickness(0);
            ToggleButton_Tower02.BorderThickness = new Thickness(0);
            ToggleButton_Tower03.BorderThickness = new Thickness(0);
            ToggleButton_Tower04.BorderThickness = new Thickness(0);
            ToggleButton_Tower05.BorderThickness = new Thickness(0);
            ToggleButton_Tower06.BorderThickness = new Thickness(0);
        }

        private void showNextWave()
        {
            WAVETYPE? waveType =  this.worldManager.GetCurrentWaveType();
            if (waveType == null)
            {
                waveType = WAVETYPE.WAVE1;
            }
            else
            {
                if ((waveType == WAVETYPE.WAVE5) && (this.worldManager.getActiveID() == 0))
                {
                    waveType = WAVETYPE.WAVE11;
                    this.worldManager.LoadWorld(1);
                    WorldIndex = 1;
                    PlayerMoney += AddedMoneyAfterLevel;
                }
                else
                {
                    waveType++;
                }
            }

            NextWave_EnemyTypes.Children.Clear();

            List<ENEMYTYPE> enemyTypes;

            if (WaveManager.DefaultWaves_Level1.ContainsKey((WAVETYPE)waveType))
            {
                enemyTypes = WaveManager.DefaultWaves_Level1[(WAVETYPE)waveType].GetTypesOfEnemies();
            }
            else
            {
                enemyTypes = WaveManager.DefaultWaves_Level2[(WAVETYPE)waveType].GetTypesOfEnemies();
            }

            foreach (ENEMYTYPE enemyType in enemyTypes)
            {
                EnemyStats enemyStats = EnemyManager.DefaultEnemies[enemyType];

                Image enemyImage = new Image();
                enemyImage.Source = new BitmapImage(new Uri(String.Format("../Images/Enemies/{0}.png", enemyStats.EnemyType.ToString()), UriKind.Relative));

                TextBlock enemyText_HP = new TextBlock();
                if (WaveManager.DefaultWaves_Level1.ContainsKey((WAVETYPE)waveType))
                {
                    enemyText_HP.Text = ApplicationResources.Get("HP_Label") + " " + (enemyStats.Hp + WaveManager.DefaultWaves_Level1[(WAVETYPE)waveType].WaveDifficultyModifier).ToString();
                }
                else
                {
                    enemyText_HP.Text = ApplicationResources.Get("HP_Label") + " " + (enemyStats.Hp + WaveManager.DefaultWaves_Level2[(WAVETYPE)waveType].WaveDifficultyModifier).ToString();
                }

                TextBlock enemyText_Armor = new TextBlock();
                if (WaveManager.DefaultWaves_Level1.ContainsKey((WAVETYPE)waveType))
                {
                    enemyText_Armor.Text = ApplicationResources.Get("Armor_Label") + " " + (enemyStats.Armor + WaveManager.DefaultWaves_Level1[(WAVETYPE)waveType].WaveDifficultyModifier).ToString();
                }
                else
                {
                    enemyText_Armor.Text = enemyText_Armor.Text = ApplicationResources.Get("Armor_Label") + " " + (enemyStats.Armor + WaveManager.DefaultWaves_Level2[(WAVETYPE)waveType].WaveDifficultyModifier).ToString();
                }

                TextBlock enemyText_Speed = new TextBlock();
                enemyText_Speed.Text = ApplicationResources.Get("Speed_Label") + " " + enemyStats.Speed.ToString();
                TextBlock enemyText_MoneyForKilling = new TextBlock();
                enemyText_MoneyForKilling.Text = ApplicationResources.Get("Coins_Label") + " " + enemyStats.MoneyForKilling.ToString();

                StackPanel enemyStackPanel = new StackPanel();
                enemyStackPanel.Orientation = System.Windows.Controls.Orientation.Vertical;
                enemyStackPanel.Children.Add(enemyImage);
                enemyStackPanel.Children.Add(enemyText_HP);
                enemyStackPanel.Children.Add(enemyText_Armor);
                enemyStackPanel.Children.Add(enemyText_Speed);
                enemyStackPanel.Children.Add(enemyText_MoneyForKilling);

                Border enemyBorder = new Border();
                enemyBorder.BorderThickness = new Thickness(3.0);
                enemyBorder.BorderBrush = new SolidColorBrush(Colors.Yellow);
                enemyBorder.Child = enemyStackPanel;

                NextWave_EnemyTypes.Children.Add(enemyBorder);
            }

            animation_NextWave_Show.Begin();
        }

        private void Page_GamePage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Pages/MainPage.xaml", UriKind.Relative));
        }

        protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            GamePage.SaveGameState();

            NavigationService.Navigate(new Uri("/Pages/MainPage.xaml", UriKind.Relative));
        }

        private void NextWave_BuildingMode_Click(object sender, RoutedEventArgs e)
        {            
            animation_NextWave_Hide_BuildingMode.Begin();
        }

        private void NextWave_LaunchWave_Click(object sender, RoutedEventArgs e)
        {
            Button_NextWave.Visibility = System.Windows.Visibility.Collapsed;
            animation_NextWave_Hide_LaunchWave.Begin();
        }

        void animation_NextWave_Hide_BuildingMode_Completed(object sender, EventArgs e)
        {
            TextBlock_WaveNumber.Visibility = System.Windows.Visibility.Collapsed;
            Button_NextWave.Visibility = System.Windows.Visibility.Visible;
            TextBlock_GameState.Text = ApplicationResources.Get("BuildingMode_Label");
        }

        void animation_NextWave_Hide_LaunchWave_Completed(object sender, EventArgs e)
        {
            TextBlock_WaveNumber.Visibility = System.Windows.Visibility.Visible;
            this.worldManager.LaunchNextWave();

            TextBlock_GameState.Text = ApplicationResources.Get("WaveRunning_Label");

            isSpecialAttackActive = true;
            Image_SpecialAttack.Source = new BitmapImage(new Uri("../Images/OtherIcons/special_attack_on.png", UriKind.Relative));

            TextBlock_WaveNumber.Text = StringFormatting.FormatTowerStatus(TextBlock_WaveNumber.Text, WaveManager.CurrentWaveType.ToString().Remove(0, WaveManager.CurrentWaveType.ToString().Length -1), WaveManager.DefaultWaves_Level1.Count);
        }

        private void Button_NextWave_Click(object sender, RoutedEventArgs e)
        {
            Button_NextWave.Visibility = System.Windows.Visibility.Collapsed;           
            animation_NextWave_Show.Begin();
        }

        void animation_NextWave_Show_Completed(object sender, EventArgs e)
        {
            TextBlock_WaveNumber.Visibility = System.Windows.Visibility.Visible;
        }

        void Instance_ShakeGesture(object sender, ShakeGestureEventArgs e)
        {
            if (e.ShakeType == ShakeType.Z)
            {
                this.worldManager.SpeciaAttack();
                time = 0;
                isSpecialAttackActive = null;
                Camera.ShakeGesture();
            }
        }

        private void Button_TowerUpgrade_Click(object sender, RoutedEventArgs e)
        {
            this.worldManager.UpgradeTowers();
        }

        private void UserControl_Tap(object sender, GestureEventArgs e)
        {
            tapOnControl = true;
        }

        private int countHighScore()
        {
            string waveScore_string = this.worldManager.GetCurrentWaveType().ToString();
            waveScore_string = waveScore_string.Remove(0, waveScore_string.Length - 2);
            int waveScore;
            if (!int.TryParse(waveScore_string, out waveScore))
            {
                waveScore_string = waveScore_string.Remove(0, 1);
                if (!int.TryParse(waveScore_string, out waveScore))
                {
                    waveScore = 0;
                }
            }

            return waveScore * 2000 + PlayerMoney;
        }

        private void Button_HighScore_Save_Click(object sender, RoutedEventArgs e)
        {
            Saver.Save_HighScore(TextBox_Nickname.Text, int.Parse(TextBlock_HighScore.Text));
            Saver.Save_NickName(TextBox_Nickname.Text);
            NavigationService.Navigate(new Uri("/Pages/MainPage.xaml", UriKind.Relative));
        }

        private void Button_HighScore_DontSave_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri("/Pages/MainPage.xaml", UriKind.Relative));
        }

        public static void SaveGameState()
        {
            Saver.Save_WaveType(WaveManager.CurrentWaveType);
            Saver.Save_Difficulty(Difficulty);
            Saver.Save_PlayerHP(PlayerHP);
            Saver.Save_PlayerMoney(PlayerMoney);
            Saver.Save_Towers(TowerManager.Towers);
        }
    }
}
